import 'package:flutter/material.dart';
import 'package:wgq_dart/wgq_dart.dart';
import 'package:flutter/services.dart';

// import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';
import 'package:flutter_cupertino_datetime_picker/flutter_cupertino_datetime_picker.dart';
import 'picker.dart';

typedef InputDone = void Function(String text);
typedef DateIntervalDone = void Function(List<DateTime>);

enum DialogDemoAction {
  cancel,
  discard,
  disagree,
  agree,
}

enum DialogType {
  show,
  overlay,
}

DialogType _dialogType = DialogType.show;

/// 显示加载菊花,有黑色半透明的背景
Future<Null> WFDialogShowJhNormal({@required BuildContext? context}) async {
  return showDialog<Null>(
    context: context!,
    barrierDismissible: false,
    builder: (BuildContext context) {
      return SizedBox(
        height: 30,
        width: 30,
        child: Material(
          child: Center(child: CircularProgressIndicator()),
          color: Colors.transparent,
          type: MaterialType.transparency,
        ),
      );
    },
  );
}

OverlayEntry? overlayEntry;

/// 显示加载菊花,有黑色半透明的背景
WFDialogShowJhTransparent(
    {@required BuildContext? context, Widget? child}) async {
  _dialogType = DialogType.overlay;
  var overlayState = Overlay.of(context!);

  if (overlayEntry == null) {
    overlayEntry = new OverlayEntry(builder: (context) {
      return child == null ? Center(child: CircularProgressIndicator()) : child;
    });
  }
  overlayState!.insert(overlayEntry!);
}

///====================可以更新状态文本的对话框====================
/// 就是屏幕中间一个黑色的小方块,分上下两部分,上面一半是朵菊花在转,下面是文字,比如"loading...."
/// 要更新状态时只要直接重复调用这个方法就行 e.g:
/// 		FCDialogWithState(context: context,text: "hoho是啊的沙发斯蒂芬就是地方阿萨德分撒旦发发送到发的",iconImage: CircularProgressIndicator());
/// 		Future.delayed(Duration(seconds: 3),(){
/// 			FCDialogWithState(context: context,text: "xixi",iconImage: Icon(Icons.brightness_3,color: Colors.cyan,));
/// 		});

GlobalKey<_DialogContentViewState> keyOne = GlobalKey();

Future<Null> WFDialogWithState(BuildContext context,
    {String text = '', Widget? iconImage}) {
  bool isUpdate = keyOne.currentState != null &&
      keyOne.currentState?.getCurrentText() != text;
  if (isUpdate) {
    keyOne.currentState?.changeText(text);
    if (iconImage != null) {
      keyOne.currentState?.changeImage(iconImage);
    }
    return showDialog(
      context: context,
      builder: (BuildContext context) {
        return Container();
      },
    );
  } else {
    keyOne = GlobalKey();
    return showDialog<Null>(
      context: context,
      barrierDismissible: false,
      builder: (BuildContext context) {
        return _DialogContentView(keyOne,
            text: text,
            iconImage: iconImage == null ? Icon(Icons.error) : iconImage);
      },
    );
  }
}

class _DialogContentView extends StatefulWidget {
  final String? text;
  final Key key;
  final Widget? iconImage;

  _DialogContentView(this.key, {this.text, this.iconImage}) : super(key: key);

  @override
  _DialogContentViewState createState() => _DialogContentViewState();
}

class _DialogContentViewState extends State<_DialogContentView> {
  var _msg;
  var _currentText;
  var _imageIcon;

  void changeText(String inMsg) {
    setState(() {
      _msg = inMsg;
    });
  }

  String getCurrentText() {
    return _currentText;
  }

  void changeImage(Widget imageIcon) {
    setState(() {
      _imageIcon = imageIcon;
    });
  }

  @override
  Widget build(BuildContext context) {
    var msg = _msg ?? widget.text;
    var imageIcon = _imageIcon ?? widget.iconImage;

    _currentText = msg;

    Future<bool> _onWillPop() => new Future.value(false);
    return WillPopScope(
      onWillPop: _onWillPop,
      child: new Center(
        child: new ConstrainedBox(
          constraints: const BoxConstraints(maxWidth: 280.0),
          child: new Material(
            elevation: 24.0,
            color: Colors.transparent,
            child: Container(
              decoration: new BoxDecoration(
                color: Color.fromARGB(0xcc, 0x00, 0x00, 0x00),
                borderRadius: BorderRadius.all(
                  Radius.circular(16.0),
                ),
              ),
              child: Padding(
                padding: const EdgeInsets.only(
                    top: 17.0, bottom: 17.0, left: 30.0, right: 30.0),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    Container(
                      height: 32.0,
                      width: 32.0,
                      margin: EdgeInsets.only(bottom: 8.0),
                      child: imageIcon,
                    ),
                    Text(
                      msg,
                      style: TextStyle(color: Colors.white, fontSize: 16.0),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

/// 确认对话框,并带有两个按钮(默认名称为"确定"和"取消")
WFDialogConfirmWith2Operation(
    BuildContext context, String message, VoidCallback onEnsure,
    {String? cancelStr, String? ensureStr, VoidCallback? onCancel}) {
  ensureStr ??= "确定";
  cancelStr ??= "取消";

  final TextStyle dialogTextStyle = TextStyle(
    fontSize: 14.0,
    color: Colors.white,
  );

  _showDemoDialog<DialogDemoAction>(context,
      child: Theme(
        data: Theme.of(context).copyWith(
          dialogTheme: DialogThemeData(
            backgroundColor: Color.fromARGB(0xcc, 0x00, 0x00, 0x00),
          ),
        ),
        child: AlertDialog(
            content: Text(message, style: dialogTextStyle),
            actions: <Widget>[
              TextButton(
                  child: Text(
                    cancelStr,
                    style: TextStyle(color: Colors.white),
                  ),
                  onPressed: () {
                    if (onCancel == null) {
                      Navigator.of(context).pop();
                    } else {
                      onCancel();
                    }
                  }),
              TextButton(
                  child: Text(
                    ensureStr,
                    style: TextStyle(color: Colors.white),
                  ),
                  onPressed: () {
                    onEnsure();
                  })
            ]),
      ));
}

/// 确认对话框,并带有三个按钮(默认名称为"确定"和"取消")
WFDialogConfirmWith3Operation({
  required BuildContext context,
  required String message,
  required String titleBt1,
  required String titleBt2,
  required String titleBt3,
  required VoidCallback ontapBt1,
  required VoidCallback ontapBt2,
  required VoidCallback ontapBt3,
}) {
  final TextStyle dialogTextStyle = TextStyle(
    fontSize: 14.0,
    color: Colors.white,
  );

  _showDemoDialog<DialogDemoAction>(context,
      child: Theme(
        data: Theme.of(context).copyWith(
          dialogTheme: DialogThemeData(
            backgroundColor: Color.fromARGB(0xcc, 0x00, 0x00, 0x00),
          ),
        ),
        child: AlertDialog(
            content: Text(message, style: dialogTextStyle),
            actions: <Widget>[
              TextButton(
                child: Text(
                  titleBt1,
                  style: TextStyle(color: Colors.white),
                ),
                onPressed: ontapBt1,
              ),
              TextButton(
                child: Text(
                  titleBt2,
                  style: TextStyle(color: Colors.white),
                ),
                onPressed: ontapBt2,
              ),
              TextButton(
                child: Text(
                  titleBt3,
                  style: TextStyle(color: Colors.white),
                ),
                onPressed: ontapBt3,
              ),
            ]),
      ));
}

void _showDemoDialog<T>(BuildContext context, {Widget? child}) {
  showDialog<T>(
    context: context,
    builder: (BuildContext context) => child == null ? Container() : child,
  ).then<void>((T? value) {
    if (value != null) {}
  });
}

/// 只有一个输入框的输入对话框
WFDialogInputWithOneField(
    BuildContext context, String message, bool isPass, InputDone onEnsure,
    {String cancelStr = '取消',
    String ensureStr = "确定",
    TextInputType keyboardType = TextInputType.text,
    Color backgroundColor = const Color.fromARGB(0xcc, 0x00, 0x00, 0x00),
    Color boderColor = Colors.white,
    Color textColor = Colors.white,
    VoidCallback? onCancel,
    String defaultText = ""}) {
  TextEditingController _ctrl = TextEditingController();
  _ctrl.text = defaultText;
  _ctrl.selection =
      TextSelection(baseOffset: 0, extentOffset: _ctrl.text.length);

  String tftext = defaultText;
  _showDemoDialog<DialogDemoAction>(context,
      child: Theme(
        data: Theme.of(context).copyWith(
          dialogTheme: DialogThemeData(
            backgroundColor: backgroundColor,
          ),
        ),
        child: AlertDialog(
            content: TextField(
              controller: _ctrl,
              autofocus: true,
              keyboardType: keyboardType,
              decoration: InputDecoration(
                fillColor: Colors.white,
                hintStyle: const TextStyle(
                  color: Colors.grey,
                ),
                hintText: message,
                focusedBorder: UnderlineInputBorder(
                    borderSide: BorderSide(color: boderColor, width: 0.5)),
                enabledBorder: UnderlineInputBorder(
                    borderSide: BorderSide(color: boderColor, width: 0.5)),
              ),
              style: TextStyle(
                color: textColor,
              ),
              obscureText: isPass,
              cursorColor: textColor,
              onChanged: (txt) {
                tftext = txt;
              },
            ),
            actions: <Widget>[
              TextButton(
                  child: Text(
                    cancelStr,
                    style: TextStyle(color: textColor),
                  ),
                  onPressed: () {
                    if (onCancel == null) {
                      Navigator.of(context).pop();
                    } else {
                      onCancel();
                    }
                  }),
              TextButton(
                  child: Text(
                    ensureStr,
                    style: TextStyle(color: textColor),
                  ),
                  onPressed: () {
                    onEnsure(tftext);
                  })
            ]),
      ));
}

/// 只有一个输入框的输入对话框
/// 单独一行做提示信息,取消hint
WFDialogInputWithOneField_v2(
  BuildContext context,
  String message,
  InputDone onEnsure, {
  bool isPass = false,
  String cancelStr = '取消',
  String ensureStr = "确定",
  Color backgroundColor = const Color.fromARGB(0xcc, 0x00, 0x00, 0x00),
  Color boderColor = Colors.white,
  Color textColor = Colors.white,
  VoidCallback? onCancel,
  String defaultText = "",
  TextInputType keyboardType = TextInputType.text,
  isDecimalOnly = false,
  keepNumOfDecimal = 2,
}) {
  TextEditingController _ctrl = TextEditingController();
  _ctrl.text = defaultText;
  _ctrl.selection =
      TextSelection(baseOffset: 0, extentOffset: _ctrl.text.length);
  // TextInputType keyboardType = isDecimalOnly
  //     ? TextInputType.numberWithOptions(decimal: true)
  //     : TextInputType.text;

  String tftext = defaultText;
  _showDemoDialog<DialogDemoAction>(context,
      child: Theme(
        data: Theme.of(context).copyWith(
          dialogTheme: DialogThemeData(
            backgroundColor: backgroundColor,
          ),
        ),
        child: AlertDialog(
            content: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  message,
                  style: const TextStyle(
                    color: Colors.grey,
                  ),
                ),
                TextField(
                  controller: _ctrl,
                  autofocus: true,
                  keyboardType: keyboardType,
                  inputFormatters: isDecimalOnly
                      ? [PrecisionLimitFormatter(keepNumOfDecimal)]
                      : [],
                  decoration: InputDecoration(
                    fillColor: Colors.white,
                    focusedBorder: UnderlineInputBorder(
                        borderSide: BorderSide(color: boderColor, width: 0.5)),
                    enabledBorder: UnderlineInputBorder(
                        borderSide: BorderSide(color: boderColor, width: 0.5)),
                  ),
                  style: TextStyle(
                    color: textColor,
                  ),
                  obscureText: isPass,
                  cursorColor: textColor,
                  onChanged: (txt) {
                    tftext = txt;
                  },
                ),
              ],
            ),
            actions: <Widget>[
              TextButton(
                  child: Text(
                    cancelStr,
                    style: TextStyle(color: textColor),
                  ),
                  onPressed: () {
                    if (onCancel == null) {
                      Navigator.of(context).pop();
                    } else {
                      onCancel();
                    }
                  }),
              TextButton(
                  child: Text(
                    ensureStr,
                    style: TextStyle(color: textColor),
                  ),
                  onPressed: () {
                    onEnsure(tftext);
                  })
            ]),
      ));
}

WFDialogPickerDateInterval(
  BuildContext context,
  DateIntervalDone selectedDone, {
  String cancelStr = '取消',
  String ensureStr = "确定",
  Color backgroundColor = const Color.fromARGB(0xcc, 0x00, 0x00, 0x00),
  Color boderColor = Colors.white,
  Color textColor = Colors.white,
  VoidCallback? onCancel,
}) {
  TimeStyle dtstyle = TimeStyle.YEAR_hg_MO_hg_DAY;
  DateTime b = DateTime.now();
  DateTime e = DateTime.now();

  showDialog(
      context: context,
      builder: (context) {
        return StatefulBuilder(
          builder: (context, state) {
            return Theme(
              data: Theme.of(context).copyWith(
                dialogTheme: DialogThemeData(
                  backgroundColor: backgroundColor,
                ),
              ),
              child: AlertDialog(
                  content: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      GestureDetector(
                        onTap: () {
                          DateTimePickerLocale _locale =
                              DateTimePickerLocale.zh_cn;
                          DatePicker.showDatePicker(
                            context,
                            onConfirm: (dt, idx) {
                              b = dt;
                              state(() {});
                            },
                            initialDateTime: DateTime.now(),
                            locale: _locale,
                          );
                        },
                        behavior: HitTestBehavior.opaque,
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            Text(
                              WDTime.formatDateTime(
                                  dateTimeString: b.toString(), style: dtstyle),
                              style: TextStyle(fontSize: 14, color: textColor),
                            ),
                            Icon(
                              Icons.arrow_drop_down,
                              color: textColor,
                            ),
                          ],
                        ),
                      ),
                      Text(
                        " 到  ",
                        style: TextStyle(fontSize: 14, color: textColor),
                      ),
                      GestureDetector(
                        onTap: () {
                          DateTimePickerLocale _locale =
                              DateTimePickerLocale.zh_cn;
                          DatePicker.showDatePicker(
                            context,
                            onConfirm: (dt, idx) {
                              e = dt;
                              state(() {});
                            },
                            initialDateTime: DateTime.now(),
                            locale: _locale,
                          );
                        },
                        behavior: HitTestBehavior.opaque,
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            Text(
                              WDTime.formatDateTime(
                                  dateTimeString: e.toString(), style: dtstyle),
                              style: TextStyle(fontSize: 14, color: textColor),
                            ),
                            Icon(
                              Icons.arrow_drop_down,
                              color: textColor,
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                  actions: <Widget>[
                    TextButton(
                        child: Text(
                          cancelStr,
                          style: TextStyle(color: textColor),
                        ),
                        onPressed: () {
                          if (onCancel == null) {
                            Navigator.of(context).pop();
                          } else {
                            onCancel();
                          }
                        }),
                    TextButton(
                        child: Text(
                          ensureStr,
                          style: TextStyle(color: textColor),
                        ),
                        onPressed: () {
                          selectedDone([b, e]);
                        })
                  ]),
            );
          },
        );
      });
}

/// 取消显示的对话框或者加载框(应该与前面的方法成对出现)
/// 注意:用这个方法后不要再用Navigator.pop()方法再次关闭对话框
WFDismissDialog(BuildContext ctx) {
  if (_dialogType == null) return;
  switch (_dialogType) {
    case DialogType.show:
      Navigator.pop(ctx);
      break;
    case DialogType.overlay:
      overlayEntry?.remove();
      break;
  }
}

class PrecisionLimitFormatter extends TextInputFormatter {
  int _scale;

  PrecisionLimitFormatter(this._scale);

  RegExp exp = new RegExp("[0-9.]");
  static const String POINTER = ".";
  static const String DOUBLE_ZERO = "00";

  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    ///输入完全删除
    if (newValue.text.isEmpty) {
      return TextEditingValue();
    }

    ///只允许输入小数
    if (!exp.hasMatch(newValue.text)) {
      return oldValue;
    }

    ///包含小数点的情况
    if (newValue.text.contains(POINTER)) {
      ///包含多个小数
      if (newValue.text.indexOf(POINTER) !=
          newValue.text.lastIndexOf(POINTER)) {
        return oldValue;
      }
      String input = newValue.text;
      int index = input.indexOf(POINTER);

      ///小数点后位数
      int lengthAfterPointer = input.substring(index, input.length).length - 1;

      ///小数位大于精度
      if (lengthAfterPointer > _scale) {
        return oldValue;
      }
    } else if (newValue.text.startsWith(POINTER) ||
        newValue.text.startsWith(DOUBLE_ZERO)) {
      ///不包含小数点,不能以“00”开头
      return oldValue;
    }
    return newValue;
  }
}
